package per.srp.demo.carLink;

import com.alibaba.fastjson.JSONObject;
import per.srp.demo.carLink.Utils.CarInfoCodeTool;
import per.srp.demo.carLink.Utils.PackageObjectFromJSONObject;
import per.srp.demo.carLink.Utils.SocketOperation;
import per.srp.demo.carLink.entity.Car;
import per.srp.demo.carLink.entity.CarAndSocket;
import per.srp.demo.carLink.entity.CarCommand;
import per.srp.demo.carLink.log.CarLogger;
import per.srp.demo.carLink.log.LogType;


import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.LinkedList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CarSocketManager {
    private ServerSocket ss = null;
    private ExecutorService threadPool = null;
    private int socketTimeOut = 5*1000;
    private boolean exitFlag=false;

    public CarSocketManager(int port,int threadNum) throws IOException {
        ss = new ServerSocket(port);
        System.out.println("CarServer started on "+port+" with "+threadNum+" threads");
        threadPool = Executors.newFixedThreadPool(threadNum);
    }

    //接收socket，并封装到CarAndSocket
    public void listen(){
        while (!exitFlag){
            try {
                Socket carClient = ss.accept();
                //多线程
                threadPool.submit(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            carClient.setSoTimeout(socketTimeOut);
                            //读取内部加密字符串
                            String encodeSting = SocketOperation.read(carClient);

                            //解密字符串到JSONObject
                            JSONObject carJsonInfo = CarInfoCodeTool.deCodeToJSONObject(encodeSting);

                            System.out.print("接收到: "+encodeSting);

                            //不满足条件，丢弃
                            if(carJsonInfo==null){
                                System.out.println("丢弃");
                                CarLogger.log(LogType.LINK_FAILED,carClient,"");
                                carClient.close();
                                return;
                            }else{
                                System.out.println("进入");
                            }

                            //依据json封装对象
                            Car car = PackageObjectFromJSONObject.pack(carJsonInfo, Car.class);

                            //生成CarAndSocket
                            CarAndSocket carInfo = new CarAndSocket(carClient,car);

                            //将CarAndSocket结果传给外部
                            acceptCar(carInfo);
                        }catch (Exception e){
                            e.printStackTrace();
                        }
                    }
                });
            } catch (Exception e) {

            }
        }
    }


    public void acceptCar(CarAndSocket carInfo) throws IOException {

        CarHandler carHandler = new CarHandler(carInfo);

        //提交小车，并且获取该小车要执行的命令
        LinkedList<CarCommand> carCommands = carHandler.submitCarPackage();

        ReturnSocketHandler returnSocketHandler = new ReturnSocketHandler(carInfo);

        //让小车执行命令
        returnSocketHandler.doCommand(carCommands);

        //关闭连接
        carInfo.getSocket().close();
    }

    public void exit() throws IOException {
        threadPool.shutdown();
        ss.close();
        exitFlag=true;
    }
}
